/*
* Copyright (c) 2016 . All Rights Reserved.
*/
package com.cgmnx.admin.biz.rbac.impl;

import com.cgmnx.admin.biz.rbac.UserBiz;
import com.cgmnx.admin.common.bean.CurrentUserInfo;
import com.cgmnx.admin.common.bean.Limiter;
import com.cgmnx.admin.common.bean.Template;
import com.cgmnx.admin.common.bean.UserContext;
import com.cgmnx.admin.common.exception.Preconditions;
import com.cgmnx.admin.common.random.RandomNumberGenerator;
import com.cgmnx.admin.common.random.SecureRandomNumberGenerator;
import com.cgmnx.admin.common.util.EncryptionUtil;
import com.cgmnx.admin.dao.entity.rbac.RoleUserRelationEntity;
import com.cgmnx.admin.dao.entity.rbac.UserEntity;
import com.cgmnx.admin.model.enums.rbac.OperationType;
import com.cgmnx.admin.model.enums.rbac.UserStatus;
import com.cgmnx.admin.service.aop.Loggable;
import com.cgmnx.admin.service.rbac.RoleUserRelationService;
import com.cgmnx.admin.service.rbac.UserService;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;

/**
 * @author: created  Date: 16/12/14 Time: 上午9:39
 * @version: 1.0
 */
@Slf4j
@Service
public class UserBizImpl implements UserBiz {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleUserRelationService roleUserRelationService;

    /**
     * {@inheritDoc}
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional
    @Loggable(description = "保存用户信息", type = OperationType.USER)
    public Integer save(final UserEntity entity) {

        return new Template<Integer>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(entity, "用户信息不能为空");
            }

            @Override
            protected Integer exec() throws Exception {

                RandomNumberGenerator generator = new SecureRandomNumberGenerator();
                entity.setSalt(generator.nextString(8));

                String encryptPassword = getEncryptPassword(entity);
                entity.setPassword(encryptPassword);

                // 保存用户
                userService.save(entity);

                // 保存用户对应的角色
                roleUserRelationService.saveAll(entity.getRoleList(), entity.getUserId(), entity.getCreateUser());


                //bizUserBiz.save(entity)

                return entity.getId();
            }
        }.execute();

    }

    @Override
    @Loggable(description = "更新用户信息", type = OperationType.USER)
    public Integer update(final UserEntity entity) {

        return new Template<Integer>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(entity, "用户信息不能为空");
            }

            @Override
            protected Integer exec() throws Exception {

                entity.setPassword(null);

                // 保存用户
                Integer id = userService.updateUser(entity);

                // 删除该用户下所有的角色
                roleUserRelationService.deleteByUserIdList(Lists.newArrayList(entity.getUserId()));

                //保存用户对应的角色
                roleUserRelationService.saveAll(entity.getRoleList(), entity.getUserId(), entity.getCreateUser());

                return id;
            }
        }.execute();
    }


    /**
     * {@inheritDoc}
     *
     * @param id 用户id
     * @return
     */
    @Override
    public Optional<UserEntity> queryById(final Integer id) {
        return new Template<Optional<UserEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(id, "用户id不能为空");
            }

            @Override
            protected Optional<UserEntity> exec() throws Exception {
                return userService.queryUserById(id);
            }
        }.execute();
    }

    @Override
    public Optional<UserEntity> queryWithRoleById(final Integer id) {
        return new Template<Optional<UserEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(id, "用户id不能为空");
            }

            @Override
            protected Optional<UserEntity> exec() throws Exception {

                Optional<UserEntity> userEntityOptional = userService.queryUserById(id);
                if (userEntityOptional.isPresent()) {
                    UserEntity userEntity = userEntityOptional.get();
                    userEntity.setRoleList(getRoleList(userEntity));
                }

                return userEntityOptional;
            }
        }.execute();
    }

    private List<Integer> getRoleList(UserEntity userEntity) {
        List<RoleUserRelationEntity> roleUserRelationEntities = roleUserRelationService.queryByUserIdList(Lists.newArrayList(userEntity.getUserId()));

        if (CollectionUtils.isEmpty(roleUserRelationEntities)) {
            return Collections.emptyList();
        }
        return FluentIterable.from(roleUserRelationEntities).transform(new Function<RoleUserRelationEntity, Integer>() {
            @Override
            public Integer apply(RoleUserRelationEntity input) {

                if (input == null) {
                    return null;
                }

                return input.getId();
            }
        }).toList();


    }

    /**
     * {@inheritDoc}
     *
     * @param searchName userd或者真实姓名
     * @return
     */
    @Override
    public Integer count(final String searchName, final String userId) {
        return new Template<Integer>() {

            @Override
            protected void check() {

            }

            @Override
            protected Integer exec() throws Exception {
                return userService.count(searchName, userId);
            }
        }.execute();
    }

    /**
     * {@inheritDoc}
     *
     * @param searchName 代表的是userId或者真实姓名
     * @param limiter    分页信息
     * @return
     */
    @Override
    public List<UserEntity> queryPage(final String searchName, final String userId, final Limiter limiter) {
        return new Template<List<UserEntity>>() {

            @Override
            protected void check() {
                Preconditions.checkNotNull(limiter, "分页信息不能为空");
            }

            @Override
            protected List<UserEntity> exec() throws Exception {
                return userService.queryPage(searchName, userId, limiter);
            }
        }.execute();
    }

    @Override
    public Optional<UserEntity> queryByUserId(final String userId) {
        return new Template<Optional<UserEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkArgument(StringUtils.isNotBlank(userId), "用户id不能为空");
            }

            @Override
            protected Optional<UserEntity> exec() throws Exception {
                return userService.queryUserByUserId(userId);
            }
        }.execute();
    }


    @Override
    @Loggable(description = "更新用户为有效状态", type = OperationType.USER)
    public Boolean enable(final List<Integer> idList, CurrentUserInfo operator) {
        return updateUserStatus(idList, UserStatus.ENABLE, operator.getUserName());
    }

    @Override
    @Loggable(description = "更新用户为无效状态", type = OperationType.USER)
    public Boolean disable(final List<Integer> idList, CurrentUserInfo operator) {
        return updateUserStatus(idList, UserStatus.DISABLE, operator.getUserName());
    }

    /**
     * 更新订单状态
     *
     * @param idList
     * @param status
     * @return
     */
    private Boolean updateUserStatus(final List<Integer> idList, final UserStatus status, final String operator) {
        return new Template<Boolean>() {
            @Override
            protected void check() {
                Preconditions.checkArgument(CollectionUtils.isNotEmpty(idList), "用户id列表不能为空");
            }

            @Override
            protected Boolean exec() throws Exception {
                int count = userService.updateStatus(idList, status, operator);
                log.info("更新用户状态返回的数据：{}", count);
                return Boolean.TRUE;
            }
        }.execute();
    }

    @Override
    @Loggable(description = "修改用户密码", type = OperationType.USER)
    public boolean updatePassword(final UserEntity entity, final String oldPassword, final String newPassword) {
        return new Template<Boolean>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(entity, "用户不能为空");
            }

            @Override
            protected Boolean exec() throws Exception {
                String encryptPassword = getEncryptPassword(entity.getUserId(), oldPassword, entity.getSalt());

                Preconditions.checkArgument(StringUtils.equals(encryptPassword, entity.getPassword()), "旧密码不正确");


                String encryptNewPassword = getEncryptPassword(entity.getUserId(), newPassword, entity.getSalt());

                entity.setPassword(encryptNewPassword);

                CurrentUserInfo userInfo = UserContext.getUserInfo();
                if (userInfo != null) {
                    entity.setUpdateUser(userInfo.getUserName());
                }

                // 保存用户
                userService.updateUser(entity);

                return Boolean.TRUE;

            }
        }.execute();
    }

    @Override
    public List<UserEntity> queryByIdList(final List<Integer> idList) {
        return new Template<List<UserEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkArgument(CollectionUtils.isNotEmpty(idList), "用户id不能为空");
            }

            @Override
            protected List<UserEntity> exec() throws Exception {
                return userService.queryByIdList(idList);
            }
        }.execute();
    }

    /**
     * 加密用户的密码
     *
     * @param entity
     * @return
     */
    private String getEncryptPassword(UserEntity entity) {
        return EncryptionUtil.encryptData(entity.getUserId(), entity.getPassword(), entity.getSalt());
    }

    /**
     * 加密用户的密码
     *
     * @param userId
     * @return
     */
    private String getEncryptPassword(String userId, String password, String salt) {
        return EncryptionUtil.encryptData(userId, password, salt);
    }


}